/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 */

package pl.droidsonroids.gif;

import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.components.element.Element;
import ohos.agp.components.element.PixelMapElement;
import ohos.agp.render.Canvas;
import ohos.app.Context;
import ohos.global.resource.NotExistException;
import ohos.global.resource.ResourceManager;
import ohos.global.resource.WrongTypeException;

import java.io.IOException;

public class GifTextView extends Text implements Component.BindStateChangedListener, Component.DrawTask{
	private GifViewUtils.GifViewAttributes viewAttributes;

	/**
	 * A corresponding superclass constructor wrapper.
	 *
	 * @param context
	 */
	public GifTextView(Context context) {
		super(context);
		addDrawTask(this);
	}

	public GifTextView(Context context, AttrSet attrs) throws NotExistException, WrongTypeException, IOException {
		super(context, attrs);
		addDrawTask(this);
//		init(attrs, null, 0);
	}

	public GifTextView(Context context, AttrSet attrs, String styleName) throws NotExistException, WrongTypeException, IOException {
		super(context, attrs, styleName);
		addDrawTask(this);
//		init(attrs, styleName, 0);
	}

/*	public GifTextView(Context context, AttrSet attrs, String defStyle, int defStyleRes) throws NotExistException, WrongTypeException, IOException {
		super(context, attrs, defStyle);
//		super(context, attrs, defStyle, defStyleRes);
		init(attrs, defStyle, defStyleRes);
	}*/

	private static void setDrawablesVisible(final Element[] drawables, final boolean visible) {
		for (final Element drawable : drawables) {
			if (drawable != null) {
				drawable.setVisible(visible, false);
			}
		}
	}
	private void init(AttrSet attrs, String defStyle, int defStyleRes) throws IOException, NotExistException, WrongTypeException {
		if (attrs != null) {
			Element left = getGifOrDefaultDrawable(attrs.getAttr("drawableLeft").get().getIntegerValue());
			Element top = getGifOrDefaultDrawable(attrs.getAttr("drawableTop").get().getIntegerValue());
			Element right = getGifOrDefaultDrawable(attrs.getAttr("drawableRight").get().getIntegerValue());
			Element bottom = getGifOrDefaultDrawable(attrs.getAttr("drawableBottom").get().getIntegerValue());
			Element start = getGifOrDefaultDrawable(attrs.getAttr("drawableStart").get().getIntegerValue());
			Element end = getGifOrDefaultDrawable(attrs.getAttr("drawableEnd").get().getIntegerValue());

				if (getLayoutDirection() == LayoutDirection.LTR) {
				if (start == null) {
					start = left;
				}
				if (end == null) {
					end = right;
				}
			} else {
				if (start == null) {
					start = right;
				}
				if (end == null) {
					end = left;
				}
			}
//			setCompoundDrawablesRelativeWithIntrinsicBounds(start, top, end, bottom);
			setAroundElements(start, top, end, bottom);
			setBackground(getGifOrDefaultDrawable(attrs.getAttr("background").get().getIntegerValue()));
//			viewAttributes = new GifViewUtils.GifViewAttributes(this, attrs, defStyle, defStyleRes);
			viewAttributes = new GifViewUtils.GifViewAttributes(this, attrs, 0, 0);
			applyGifViewAttributes();
		}
		viewAttributes = new GifViewUtils.GifViewAttributes();
	}

	private void applyGifViewAttributes() {
		if (viewAttributes.mLoopCount < 0) {
			return;
		}
		for (final Element element : getAroundElements()) {
			GifViewUtils.applyLoopCount(viewAttributes.mLoopCount, element);
		}
		for (final Element element : getAroundElementsRelative()) {
			GifViewUtils.applyLoopCount(viewAttributes.mLoopCount, element);
		}
		GifViewUtils.applyLoopCount(viewAttributes.mLoopCount, getBackgroundElement());
	}

	@SuppressWarnings("deprecation") //Resources#getDrawable(int)
	private Element getGifOrDefaultDrawable(int resId) throws IOException, NotExistException, WrongTypeException {
		if (resId == 0) {
			return null;
		}
		final ResourceManager resources = getResourceManager();
		final String resourceTypeName = resources.getIdentifier(resId);
//		TODO - isInEditMode()
//		if (!isInEditMode() && GifViewUtils.SUPPORTED_RESOURCE_TYPE_NAMES.contains(resourceTypeName)) {
			try {
				return new GifDrawable(getContext(), resources, resId);
			} catch (IOException | NotExistException ignored) {
				// ignored
			}
//		}
		/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
			return resources.getElement(resId, getContext().getTheme());
		} else {*/
			return GifViewUtils.getElement(getContext(), resId);
//		}
	}

//	setAroundElements​(Element left, Element top, Element right, Element bottom) can be used directly
	private Element left, right, top, bottom, backGround;
/*	@Override
	public void setAroundElements​(int left, int top, int right, int bottom) {
		setAroundElements​(getGifOrDefaultDrawable(left), getGifOrDefaultDrawable(top), getGifOrDefaultDrawable(right), getGifOrDefaultDrawable(bottom));
	}*/
	public void setElements(Element left, Element top, Element right, Element bottom) {

		this.left = left;
		this.right = right;
		this.top = top;
		this.bottom = bottom;
        ((GifDrawable)this.left).setElementCallback(this);
	}

	public void setLoopCount(int count) {
		((GifDrawable)this.left).setLoopCount(count);
		((GifDrawable)this.right).setLoopCount(count);
		((GifDrawable)this.top).setLoopCount(count);
		((GifDrawable)this.bottom).setLoopCount(count);
	}

//	setAroundElementsRelative​(Element start, Element top, Element end, Element bottom) can be used directly
	/*@Override
	public void setCompoundDrawablesRelativeWithIntrinsicBounds(int start, int top, int end, int bottom) {
		setCompoundDrawablesRelativeWithIntrinsicBounds(getGifOrDefaultDrawable(start), getGifOrDefaultDrawable(top), getGifOrDefaultDrawable(end), getGifOrDefaultDrawable(bottom));
	}*/

	/*@Override
	public Sequenceable onSaveInstanceState() {
		Element[] savedDrawables = new Element[7];
		if (viewAttributes.freezesAnimation) {
			Element[] compoundDrawables = getAroundElements();
			System.arraycopy(compoundDrawables, 0, savedDrawables, 0, compoundDrawables.length);

            Element[] compoundDrawablesRelative = getAroundElementsRelative();
            savedDrawables[4] = compoundDrawablesRelative[0]; //start
            savedDrawables[5] = compoundDrawablesRelative[2]; //end
            savedDrawables[6] = getBackgroundElement();
		}
		return new GifViewSavedState(super.onSaveInstanceState(), savedDrawables);
	}*/

	/*@Override
	public void onRestoreInstanceState(Sequenceable state) {
		if (!(state instanceof GifViewSavedState)) {
			super.onRestoreInstanceState(state);
			return;
		}
		GifViewSavedState ss = (GifViewSavedState) state;
		super.onRestoreInstanceState(ss.getSuperState());

		Element[] compoundDrawables = getAroundElements();
		ss.restoreState(compoundDrawables[0], 0);
		ss.restoreState(compoundDrawables[1], 1);
		ss.restoreState(compoundDrawables[2], 2);
		ss.restoreState(compoundDrawables[3], 3);
        Element[] compoundDrawablesRelative = getAroundElementsRelative();
        ss.restoreState(compoundDrawablesRelative[0], 4);
        ss.restoreState(compoundDrawablesRelative[2], 5);
        ss.restoreState(getBackgroundElement(), 6);
	}*/

/*	@Override
	protected void onAttachedToWindow() {
		super.onAttachedToWindow();
		setCompoundDrawablesVisible(true);
	}

	@Override
	protected void onDetachedFromWindow() {
		super.onDetachedFromWindow();
		setCompoundDrawablesVisible(false);
	}*/

	public void setBackgroundResource(int resId) throws NotExistException, WrongTypeException, IOException {
		setBackground(getGifOrDefaultDrawable(resId));
	}

	private void setCompoundDrawablesVisible(final boolean visible) {
		setDrawablesVisible(getAroundElements(), visible);
        setDrawablesVisible(getAroundElementsRelative(), visible);
    }

	public void setFreezesAnimation(boolean freezesAnimation) {
		viewAttributes.freezesAnimation = freezesAnimation;
	}

	@Override
	public void onComponentBoundToWindow(Component component) {
		setCompoundDrawablesVisible(true);
	}

	@Override
	public void onComponentUnboundFromWindow(Component component) {
		setCompoundDrawablesVisible(false);
	}
	@Override
	public void onDraw(Component component, Canvas canvas) {
		if(backGround != null) {
			Element ele = new PixelMapElement(((GifDrawable)backGround).mPixelMap);
			setBackground(ele);
		}
		if(left == null || right == null || top == null || bottom == null)
			return;
		Element ele1 = new PixelMapElement(((GifDrawable)left).mPixelMap);
		Element ele2 = new PixelMapElement(((GifDrawable)top).mPixelMap);
		Element ele3 = new PixelMapElement(((GifDrawable)right).mPixelMap);
		Element ele4 = new PixelMapElement(((GifDrawable)bottom).mPixelMap);
		setAroundElementsRelative(ele1, ele2, ele3, ele4);

//		backGround.drawToCanvas(canvas);
	}

	public void setBackgroundElement(Element element) {
		backGround = element;
		((GifDrawable)backGround).setElementCallback(this);
	}

	@Override
	public Element getLeftElement() {
		return left;
	}

	@Override
	public Element getRightElement() {
		return right;
	}

	@Override
	public Element getTopElement() {
		return top;
	}

	@Override
	public Element getBottonElement() {
		return bottom;
	}

	@Override
	public Element getBackgroundElement() {
		return backGround;
	}
}
